<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!--

    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.

-->
<HTML>
<HEAD>
<TITLE>Lookup Library API</TITLE>
<link rel="Stylesheet" href="@TOP@/prose.css" type="text/css" title="NetBeans Open APIs Style">
</HEAD>
<BODY>
<H1>Lookup library API</H1>
<p>
This document describes usage of the API provided by the Lookup Library. In this
document we assume that someone has already provided us with a lookup
implementation (for those seeking how to write a lookup implementation please
check <A href="lookup-spi.html">the SPI document</A>).

<H2> Getting the lookup </H2>

The first question you might ask is this: how can I get hold of a
lookup instance? There are basically two ways how you can get it.

<H3> Global lookup </H3>
As you can see in the

<a href="@TOP@org/openide/util/Lookup.html">Lookup</a>

Javadoc there is a static method

<pre><a href="@TOP@org/openide/util/Lookup.html#getDefault--">public static Lookup getDefault()</a></pre>

The object returned from this method is
a global lookup that can serve as a central place for registering services.
The default implementation is a lookup that implements
<a href="https://docs.oracle.com/javase/1.5.0/docs/guide/jar/jar.html#Service%20Provider">
the JDK JAR services</A>
mechanism and delegates to <samp>META-INF/services/name.of.Class</samp> files.
<P>
If you want to add your class to this lookup just create a file in your
jar file under the <code>META-INF</code> directory (e.g. <samp>META-INF/services/com.my.APIClass</samp>)
and let the file contain only one line of text

<pre>com.foo.impl.ImplOfTheAPI</pre>

<p>(This is more easily done using the <code>@ServiceProvider</code> annotation.)</p>

The following code will return you a newly created instance of
<code>com.foo.impl.ImplOfTheAPI</code>:

<PRE>
   <font class="keyword">import</FONT> org.openide.util.Lookup;
   return Lookup.getDefault().lookup(com.my.APIClass.class);
</PRE>

<H3> Local lookup </H3>

This is just a reminder that whenever you find a method called getLookup
or similar returning a lookup instance, the provided lookup is <EM>not</EM> the
general lookup described in the previous paragraph. Rather, it is a private lookup
implementation that is usually bound to the object you invoked the method on.

<H2> Use of Lookup.Template and Lookup.Result </H2>

There are more ways how you can ask lookup besides the variant with one class
parameter. If you want more functionality, you have to implement the interface
Lookup.Template and pass an instance of such object to the lookup call.
<p>
<EM>Note:</EM> If you use Lookup.Template, the object returned from the lookup is
<EM>not</EM> the object you are looking for but rather a result object
(Lookup.Result). You can call methods on such a result object to get the actual
results.
<p>
Let's examine following example:

<pre>
        <font class="keyword">import</FONT> org.openide.util.Lookup;

        <font class="type">Lookup</font> <font class="variable-name">lookup</font> = ...;
        Lookup.<font class="type">Template</font> <font class="variable-name">template</font> = <font class="keyword">new</font> Lookup.<font class="type">Template</font>(MyService.<font class="keyword">class</font>);
        Lookup.<font class="type">Result</font> <font class="variable-name">result</font> = lookup.lookup(template);
        <font class="type">Collection</font> <font class="variable-name">c</font> = result.allInstances();
        <font class="keyword">for</font> (<font class="type">Iterator</font> <font class="variable-name">i</font> = c.iterator(); i.hasNext(); ) {
            <font class="type">MyService</font> <font class="variable-name">s</font> = (<font class="type">MyService</font>)i.next();
            s.callMyService();
        }
</pre>

In this example the call to method lookup(...) returns immediately because the
result object can be constructed even without real results. The first time you
ask for the result object by calling r.allInstances(), the lookup has to supply you
the real results and this method can block until the required data are really
available.
<p>
If you are not interested in all objects as in the previous example, you can use the
template to ask for one resulting object (wrapped in special Item instance):
<pre>
        <font class="keyword">import</FONT> org.openide.util.Lookup;

        <font class="type">Lookup</font> <font class="variable-name">lookup</font> = ...;
        Lookup.<font class="type">Template</font> <font class="variable-name">template</font> = <font class="keyword">new</font> Lookup.<font class="type">Template</font>(MyService.<font class="keyword">class</font>);
        Lookup.<font class="type">Item</font> <font class="variable-name">item</font> = lookup.lookupItem(template);
        <font class="type">MyService</font> <font class="variable-name">s</font> = (<font class="type">MyService</font>)item.getInstance();
        s.callMyService();
</pre>

Again, the Item object can construct the real instance only if you call
getInstance. The item can be useful even without calling getInstance - you can get
its display name or an unique id. You can use this information, for example, for
constructing menu items without the need to instantiate (or even load!)
the class implementing the functionality. Only when the real functionality is
needed (e.g. the user has selected the menu item) you can call getInstance
and call the real meat of the implementation.

<H2> Listenning on lookup changes </H2>
There is one additional piece of functionality bound to the Lookup.Result object worth
mentioning: you can attach a listener to it and be informed about any changes in
the lookup. This might be extremly usefull when the lookup dynamically changes
(from other threads). The listener can keep state of your object up-to-date even
in cases where the lookup changes asynchronously.
<p>
So here is some sample code using the listenner:

<pre>
        <font class="keyword">import</FONT> org.openide.util.Lookup;
        <font class="keyword">import</FONT> org.openide.util.LookupListener;
        <font class="keyword">import</FONT> org.openide.util.LookupEvent;

        <font class="type">Lookup</font> <font class="variable-name">lookup</font> = ...;
        Lookup.<font class="type">Template</font> <font class="variable-name">template</font> = <font class="keyword">new</font> Lookup.<font class="type">Template</font>(MyService.<font class="keyword">class</font>);
        <font class="keyword">final</font> <font class="variable-name">Lookup</font>.<font class="type">Result</font> <font class="variable-name">result</font> = lookup.lookup(template);
        result.addLookupListener(<font class="keyword">new</font> <font class="type">LookupListener</font>() {
            <font class="keyword">public</font> <font class="type">void</font> <font class="function-name">resultChanged</font>(<font class="type">LookupEvent</font> <font class="variable-name">e</font>) {
                reaction(result);
            }
        });
        reaction(result);
    }
    <font class="keyword">private</font> <font class="keyword">static</font> <font class="type">void</font> <font class="function-name">reaction</font>(Lookup.<font class="type">Result</font> <font class="variable-name">r</font>) {
        <font class="keyword">for</font> (<font class="type">Iterator</font> <font class="variable-name">i</font> = r.allInstances().iterator(); i.hasNext(); ) {
            <font class="type">MyService</font> <font class="variable-name">s</font> = (<font class="type">MyService</font>)i.next();
            s.callMyService();
        }
    }
</pre>

Please note that we first attach a listener and then call the reaction method.
This ensures that we always get the newest possible state. Also you must be
careful in the reaction method since it can be called from two different
threads simultaneously (your code has to be prepared for this).
</BODY>
</HTML>
